﻿/*********************************
 * 标题：公共助手类
 * 描述：系统公共助手类，存放一般公共方法
 * 开发：单车上的程序猿（2014.10.24）
 * 编辑：      
 * 备注：  
 * ******************************/
using System;
using System.Net;
using QiBu.Api.Helper.Entities;
using System.Web.Mvc;
namespace QiBu.Api.Helper.Common
{
    /// <summary>
    /// 公共助手类
    /// </summary>
    public class CommonHelper
    {
        #region 数据验证和异常

        /// <summary>
        ///     检验参数合法性，数值类型不能小于0，引用类型不能为null，否则抛出相应异常
        /// </summary>
        /// <param name="arg"> 待检参数 </param>
        /// <param name="argName"> 待检参数名称 </param>
        /// <param name="canZero"> 数值类型是否可以等于0 </param>
        /// <exception cref="ComponentException" />
        public static void CheckArgument(object arg, string argName, bool canZero = false)
        {
            if (arg == null)
            {
                ArgumentNullException e = new ArgumentNullException(argName);
                throw ThrowComponentException(string.Format("参数 {0} 为空引发异常。", argName), e);
            }
            Type type = arg.GetType();
            if (type.IsValueType && type.IsNumeric())
            {
                bool flag = !canZero ? arg.CastTo(0.0) <= 0.0 : arg.CastTo(0.0) < 0.0;
                if (flag)
                {
                    ArgumentOutOfRangeException e = new ArgumentOutOfRangeException(argName);
                    throw ThrowComponentException(string.Format("参数 {0} 不在有效范围内引发异常。具体信息请查看系统日志。", argName), e);
                }
            }
            if (type == typeof(Guid) && (Guid)arg == Guid.Empty)
            {
                ArgumentNullException e = new ArgumentNullException(argName);
                throw ThrowComponentException(string.Format("参数{0}为空Guid引发异常。", argName), e);
            }
        }

        /// <summary>
        ///     向调用层抛出组件异常
        /// </summary>
        /// <param name="msg"> 自定义异常消息 </param>
        /// <param name="e"> 实际引发异常的异常实例 </param>
        public static ComponentException ThrowComponentException(string msg, Exception e = null)
        {
            if (string.IsNullOrEmpty(msg) && e != null)
            {
                msg = e.Message;
            }
            else if (string.IsNullOrEmpty(msg))
            {
                msg = "未知组件异常，详情请查看日志信息。";
            }
            return e == null ? new ComponentException(string.Format("组件异常：{0}", msg)) : new ComponentException(string.Format("组件异常：{0}", msg), e);
        }

        /// <summary>
        ///     向调用层抛出数据访问层异常
        /// </summary>
        /// <param name="msg"> 自定义异常消息 </param>
        /// <param name="e"> 实际引发异常的异常实例 </param>
        public static DataAccessException ThrowDataAccessException(string msg, Exception e = null)
        {
            if (string.IsNullOrEmpty(msg) && e != null)
            {
                msg = e.Message;
            }
            else if (string.IsNullOrEmpty(msg))
            {
                msg = "未知数据访问层异常，详情请查看日志信息。";
            }
            return e == null
                ? new DataAccessException(string.Format("数据访问层异常：{0}", msg))
                : new DataAccessException(string.Format("数据访问层异常：{0}", msg), e);
        }

        /// <summary>
        ///     向调用层抛出数据访问层异常
        /// </summary>
        /// <param name="msg"> 自定义异常消息 </param>
        /// <param name="e"> 实际引发异常的异常实例 </param>
        public static BusinessException ThrowBusinessException(string msg, Exception e = null)
        {
            if (string.IsNullOrEmpty(msg) && e != null)
            {
                msg = e.Message;
            }
            else if (string.IsNullOrEmpty(msg))
            {
                msg = "未知业务逻辑层异常，详情请查看日志信息。";
            }
            return e == null ? new BusinessException(string.Format("业务逻辑层异常：{0}", msg)) : new BusinessException(string.Format("业务逻辑层异常：{0}", msg), e);
        }

        #endregion

        #region 获取主机信息

        /// <summary>
        /// 获取服务器信息
        /// </summary>
        /// <returns></returns>
        public static ServerModel GetHostInfo()
        {
            var ip = Dns.GetHostAddresses(Dns.GetHostName());
            var model = new ServerModel() { 
                MemTotal = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64 / 1024,
                ServerSys = Environment.OSVersion.VersionString,
                ServerAddress = ip[0].ToString(),
                ProcessorCount = Environment.ProcessorCount,
                ServerSoft = System.Web.HttpContext.Current.Request.ServerVariables["SERVER_SOFTWARE"]
            };
            return model;
        }

        public class ServerModel
        {
            public long MemTotal { get; set; }// 内存占用量
            public string ServerSys { get; set; }// 服务器端操作系统
            public string ServerAddress { get; set; }// 服务器端IP
            public string ServerSoft { get; set; }// 服务器端应用程序服务器
            public int ProcessorCount { get; set; }// 服务器CPU核心个数
        }

        #endregion

        #region 返回时间节点供前端查询使用

        /// <summary>
        /// 返回时间节点供前端查询使用
        /// </summary>
        /// <returns></returns>
        public static string GetDatePoint()
        {
            DateTime date = DateTime.Now;
            string today = date.ToString("yyyy年MM月dd日");
            DateTime thisWeekBegin = date.AddDays(0 - Convert.ToInt32(date.DayOfWeek.ToString("d")));//本周一
            string thisWeekBeginning = thisWeekBegin.ToString("yyyy年MM月dd日");
            string lastWeekBeginning = thisWeekBegin.AddDays(-7).ToString("yyyy年MM月dd日");
            string lastWeekEnding = thisWeekBegin.AddDays(-1).ToString("yyyy年MM月dd日");
            DateTime thisMonthBegin = date.AddDays(1 - date.Day);//本月初
            string thisMonthBeginning = thisMonthBegin.ToString("yyyy年MM月dd日");
            string lastMonthBgeinning = thisMonthBegin.AddMonths(-1).ToString("yyyy年MM月dd日");
            string lastMonthEnding = thisMonthBegin.AddDays(-1).ToString("yyyy年MM月dd日");
            DateTime thisYearBegin = date.AddDays(1 - date.DayOfYear);//本年初
            string thisYearBeginning = thisYearBegin.ToString("yyyy年MM月dd日");
            return string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}", thisWeekBeginning, today, lastWeekBeginning, lastWeekEnding, thisMonthBeginning, today, lastMonthBgeinning, lastMonthEnding, thisYearBeginning, today);
        }

        #endregion
    }
}
